package org.hentai.tri.grpc.cilent;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.stub.StreamObserver;
import org.hentai.tri.grpc.HentaiGrpc;
import org.hentai.tri.grpc.HentaiReply;
import org.hentai.tri.grpc.HentaiRequest;

import java.io.IOException;

public class HentaiGrpcClient {

    private final HentaiGrpc.HentaiBlockingStub blockingStub;

    private final HentaiGrpc.HentaiStub stub;

    public HentaiGrpcClient(int port) {
        ManagedChannel channel = ManagedChannelBuilder.forAddress("127.0.0.1", port)
                .usePlaintext()
                .build();

        blockingStub = HentaiGrpc.newBlockingStub(channel);
        stub = HentaiGrpc.newStub(channel);
    }

    public static void main(String[] args) throws IOException {
        HentaiGrpcClient client = new HentaiGrpcClient(50053);
        client.unary();
        client.stream();
        client.serverStream();
        System.in.read();
    }

    private void unary() {
        HentaiRequest request = HentaiRequest.newBuilder()
                .setName("[grpc client] hentai")
                .build();
        HentaiReply reply = blockingStub.hentai(request);
        System.out.printf("Grpc client received reply <- \"%s\"\n", reply.getMessage());

    }

    private void stream() {
        StreamObserver<HentaiReply> responseObserver = new StdoutStreamObserver<>("[grpc client][bi-stream] hentai");
        StreamObserver<HentaiRequest> requestObserver = stub.biStream(responseObserver);

        for (int i = 0; i < 10; i++) {
            HentaiRequest request = HentaiRequest.newBuilder()
                    .setName("[grpc client] hentai" + i)
                    .build();
            requestObserver.onNext(request);
        }

        requestObserver.onCompleted();
    }

    private void serverStream() {
        StdoutStreamObserver<HentaiReply> responseObserver = new StdoutStreamObserver<>("[grpc client][bi-stream] hentai");
        HentaiRequest request = HentaiRequest.newBuilder()
                .setName("[grpc client] hentai")
                .build();
        stub.serverSteam(request, responseObserver);
    }

    static class StdoutStreamObserver<T> implements StreamObserver<T> {

        private final String name;

        public StdoutStreamObserver(String name) {
            this.name = name;
        }

        @Override
        public void onNext(T data) {
            System.out.printf("%s stream <- reply:%s\n", name, data.toString());
        }

        @Override
        public void onError(Throwable throwable) {
            System.err.printf("%s stream <- error:%s\n", name, throwable.getMessage());
            throwable.printStackTrace();
        }

        @Override
        public void onCompleted() {
            System.out.printf("%s stream completed\n", name);
        }
    }

}
